namespace Warehouse

open System.Windows.Data
open System.Collections.Generic
open System.Collections.Specialized
open System.ComponentModel
open FSharp.Windows

[<AllowNullLiteral>]
type CollectionView<'T>(source : 'T ResizeArray) =
    inherit ListCollectionView(source) 

    static member ofSeq(items : 'T seq) = CollectionView<'T>(source = ResizeArray(items))

    member this.Add(item : 'T) = this.AddNewItem item |> ignore
    member this.Item 
        with get index = this.InternalList.[index] |> unbox<'T>
        and set index (value : 'T) = this.InternalList.[index] <- value

    member this.SortBy(SingleStepPropertySelector(propertyName, _) : PropertySelector<'T, _>, ?direction) = 
        this.SortDescriptions.Add(
            SortDescription(
                propertyName, 
                defaultArg direction ListSortDirection.Ascending
            )
        )

    member this.TypedFilter 
        with set filter = this.Filter <- fun item -> item |> unbox<'T> |> filter

    override this.OnCollectionChanged args = 
        base.OnCollectionChanged args

        if args.Action = NotifyCollectionChangedAction.Add
            && args.NewItems.Count = 1
        then
            let inView = this.MoveCurrentTo(args.NewItems.[0])
            assert inView

    interface IEnumerable<'T> with
        member this.GetEnumerator() = Seq.cast<'T>(this).GetEnumerator()

